package cate.game.db;

import cate.game.GameBody;
import cate.game.db.mongo.*;
import cate.game.db.mongo.kv.KvDao;
import cate.game.db.mongo.play.PlayDao;
import cate.game.db.mongo.rank.RankDao;
import cate.game.framework.GameFacilities;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean;
import org.springframework.data.repository.Repository;

import java.io.Serializable;

@SuppressWarnings("unchecked")
@Slf4j
public class GameMongoDao {

    /** 是否启用新模板 */
    public static boolean ENABLE_NEW_TEMPLATE = false;

    public RoleBaseDao roleBase;
    public RoleBagDao roleBag;
    public RoleFightDao roleFight;
    public RoleMailDao roleMail;
    public RoleFriendDao roleFriend;
    public RoleMallDao roleMall;
    public RoleChatDao roleChat;
    public RolePayDao rolePay;
    public RoleWorldDao roleWorld;
    public RoleNoteDao roleNote;
    public RoleSystemDao roleSystem;
    public KvDao kv;
    public RankDao rank;
    public MailBoxDao mailBox;
    public FriendBoxDao friendBox;
    public PlayDao play;
    public RoleStatusDao status;
    public RoleResDao res;
    public RoleFarmDao farm;
    public GuildDao guild;
    public RolePvpDao pvp;

    public RoleActivityDao activity;

    public RoleTaskDao task;

    public RoleHistoryDao history;

    public RoleShowDao show;

    public RoleTraceDao trace;

    public HeroDisplayDao heroDisplay;

    public GameStatusDao gameStatus;

    public GuildBossRankDao guildBossRank;

    private GameFacilities facilities;
    public void setup(GameBody game) {
        this.facilities = game.facilities;

        roleBase = ENABLE_NEW_TEMPLATE ? null : build(RoleBaseDao.class);
        roleBag = ENABLE_NEW_TEMPLATE ? null : build(RoleBagDao.class);
        roleFight = ENABLE_NEW_TEMPLATE ? null : build(RoleFightDao.class);
        roleMail = ENABLE_NEW_TEMPLATE ? null : build(RoleMailDao.class);
        roleFriend = ENABLE_NEW_TEMPLATE ? null : build(RoleFriendDao.class);
        roleMall = ENABLE_NEW_TEMPLATE ? null : build(RoleMallDao.class);
        roleChat = ENABLE_NEW_TEMPLATE ? null : build(RoleChatDao.class);
        rolePay = ENABLE_NEW_TEMPLATE ? null : build(RolePayDao.class);
        roleWorld = ENABLE_NEW_TEMPLATE ? null : build(RoleWorldDao.class);
        roleNote = ENABLE_NEW_TEMPLATE ? null : build(RoleNoteDao.class);
        roleSystem = ENABLE_NEW_TEMPLATE ? null : build(RoleSystemDao.class);
        kv = ENABLE_NEW_TEMPLATE ? null : build(KvDao.class);
        rank = ENABLE_NEW_TEMPLATE ? null : build(RankDao.class);
        mailBox = ENABLE_NEW_TEMPLATE ? null : build(MailBoxDao.class);
        play = ENABLE_NEW_TEMPLATE ? null : build(PlayDao.class);
        status = ENABLE_NEW_TEMPLATE ? null : build(RoleStatusDao.class);
        res = ENABLE_NEW_TEMPLATE ? null : build(RoleResDao.class);
        farm = ENABLE_NEW_TEMPLATE ? null : build(RoleFarmDao.class);
        guild = ENABLE_NEW_TEMPLATE ? null : build(GuildDao.class);
        pvp = ENABLE_NEW_TEMPLATE ? null : build(RolePvpDao.class);
        activity = ENABLE_NEW_TEMPLATE ? null : build(RoleActivityDao.class);
        task = ENABLE_NEW_TEMPLATE ? null : build(RoleTaskDao.class);
        history = ENABLE_NEW_TEMPLATE ? null : build(RoleHistoryDao.class);
        show = ENABLE_NEW_TEMPLATE ? null : build(RoleShowDao.class);
        trace = ENABLE_NEW_TEMPLATE ? null : build(RoleTraceDao.class);
        heroDisplay = ENABLE_NEW_TEMPLATE ? null : build(HeroDisplayDao.class);
        gameStatus = ENABLE_NEW_TEMPLATE ? null : build(GameStatusDao.class);
        friendBox = ENABLE_NEW_TEMPLATE ? null : build(FriendBoxDao.class);
        guildBossRank = ENABLE_NEW_TEMPLATE ? null : build(GuildBossRankDao.class);
    }

    private <T extends Repository<S, ID>, S, ID extends Serializable> T build(Class<T> clzT) {
        //long beginTime = System.currentTimeMillis();
        MongoTemplate mt = this.facilities.getMongoTemplate();
        MongoOperations operations = mt;
        MongoRepositoryFactoryBean<T, S, ID> fb = new MongoRepositoryFactoryBean<>(clzT);
        fb.setMongoOperations(operations);
        fb.afterPropertiesSet();
        //log.info("GameMongoDao build {} 消耗 {}ms", clzT, (System.currentTimeMillis()-beginTime));
        return fb.getObject();
    }
}
